package com.ruoyi.web.controller.API;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.CountLogin;
import com.ruoyi.common.core.domain.model.YuLiStudioLoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.mytools.AliyunSMS;
import com.ruoyi.common.mytools.R;
import com.ruoyi.common.mytools.Tools;
import com.ruoyi.common.mytools.jwtUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.domain.Students;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import java.time.Clock;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.time.Duration;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/api")
@Anonymous
public class ApiController extends BaseController {

    @Resource
    HttpServletRequest request;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private IVideosService videosService;

    @Autowired
    private IStudentsService studentsService;

    @Autowired
    private ICoursesService coursesService;

    @Autowired
    private ISubscribesService subscribesService;

    @Autowired
    private IOrgsService orgsService;

    @Autowired
    private IArticlesService articlesService;

    @Autowired
    private IMyfavsService myfavsService;

    @Autowired
    private IAdimgsService adimgsService;

    @Autowired
    private IActivitysService activitysService;

    @Autowired
    private IClockingService iClockingService;

    @Autowired
    private IPhotosService photosService;

    @Autowired
    private IOpencloseService opencloseService;

    //默认头像
    private String defaultHeadimg="https://yulistudio.oss-cn-shenzhen.aliyuncs.com/images/bg/yllogo.png";

    /**
     * 小程序登录请求
     */
    @PostMapping("/login")
    public R login(@RequestBody YuLiStudioLoginUser yuLiStudioLoginUser) throws Exception
    {
        try{
            String sid=yuLiStudioLoginUser.getSessionId();
            if(!StringUtils.isEmpty(sid)){

                Map<String,String> map=(Map<String,String>)redisTemplate.opsForValue().get("sid"); //取出对象
                String phoneNumber=yuLiStudioLoginUser.getPhoneNumber();
                String code=yuLiStudioLoginUser.getCode();
                System.out.println("登录的手机号: "+phoneNumber);
                System.out.println("登录code: "+code);

                //从redis中获取保存的验证码
                String savedPhone=map.get("phoneNumber");
                String savedCode = map.get("code");
                System.out.println("从redis中取出号码: "+savedPhone);
                System.out.println("从redis中取出code: "+savedCode);

                if(!phoneNumber.equals(savedPhone)){
                    redisTemplate.delete("sid");
                    return R.error("手机号码不正确,请重新获取验证码");
                }

                //验证码验证成功
                if (code.equals(savedCode)) {

                    // 验证成功，可以进行后续操作
                    redisTemplate.delete("sid");

                    //输出用户信息到前端
                    Students studentInfo=studentsService.selectStudentsByUserPhone(phoneNumber);
                    if(Objects.isNull(studentInfo)){ //用户尚未注册，第一次登录注册
                        studentInfo=new Students();
                        studentInfo.setHeadimg(defaultHeadimg); //默认头像
                        studentInfo.setUserphone(phoneNumber);
                        studentInfo.setLogname(phoneNumber);
                        studentInfo.setHeadimg("https://yulistudio.oss-cn-shenzhen.aliyuncs.com/images/bg/head.png");
                        studentInfo.setUsersex("未知");
                        studentInfo.setRemark("新用户注册");

                        //生成初始登录账号和登录密码
                        String rndPassword=Tools.generateCode4(); //生成8位大小写密码
                        studentInfo.setLogpwd(rndPassword);

                        System.out.println("初始登录账号和密码");
                        System.out.println(phoneNumber+","+rndPassword);

                        //发送短信给用户
                        AliyunSMS.SendInialLoginAndPassWord(phoneNumber,phoneNumber,rndPassword);

                        studentsService.insertStudents(studentInfo); //插入新注册信息
                    }

                    //保存用户信息Redis
                    //student_+sessionId
                    redisTemplate.opsForValue().set("student_"+sid,studentInfo);

                    //生成jwt码
                    //生成全局唯一uuid
                    Map<String,String> keys=new HashMap<String,String>();
                    keys.put("sessionid",sid);
                    String Token= jwtUtils.createToken(keys);
                    System.out.println("生成token===========>" + Token);

                    //设置token返回到客户端
                    studentInfo.setToken(Token);

                    return R.ok("登录成功").put("data",studentInfo);

                } else {
                    // 验证失败
                    return R.error("您输入验证码不正确");
                }
            }
            return R.ok("登录成功"); //为了保持同一session会话
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            return R.error(408,"登录失败,请重新获取验证码");
        }
    }

    /**
     * 用户要先注册手机账号
     * 账号密码登录
     */
    @PostMapping("/countlogin")
    public R countlogin(@RequestBody CountLogin countLogin) throws Exception
    {
        System.out.println("账号信息");
        System.out.println(countLogin);
        try{
            if(!StringUtils.isEmpty(countLogin.getLogname()) && !StringUtils.isEmpty(countLogin.getLogpwd())){
                Students studentInfo=studentsService.selectStudentsByLoginCount(countLogin.getLogname(),countLogin.getLogpwd());
                if(!Objects.isNull(studentInfo)){ //用户尚未注册，第一次登录注册

                    String sid=request.getSession().getId();
                    System.out.println("当前会话id:==>"+sid);

                    //保存用户信息Redis
                    redisTemplate.opsForValue().set("student_"+sid,studentInfo);

                    //生成jwt码
                    //生成全局唯一uuid
                    Map<String,String> keys=new HashMap<String,String>();
                    keys.put("sessionid",sid);
                    String Token= jwtUtils.createToken(keys);
                    System.out.println("生成token===========>" + Token);

                    //设置token返回到客户端
                    studentInfo.setToken(Token);

                    return R.ok("登录成功").put("data",studentInfo);

                }else{
                    return R.error(409,"尚未设置登录账号，前前往个人中心设置"); //为了保持同一session会话
                }
            }
            return R.ok("登录成功"); //为了保持同一session会话
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            return R.error(408,"登录失败,账号不存在");
        }
    }


    /**
     * 发送验证码
     */
    @PostMapping("/sendMessage")
    public R sendMessage(@RequestBody YuLiStudioLoginUser yuLiStudioLoginUser) throws Exception
    {
        Map<String,String> map=new HashMap<>();
        String phoneNumber=yuLiStudioLoginUser.getPhoneNumber();
        // 假设验证手机号成功，生成一个随机的验证码
        String verificationCode = Tools.generateCode4();

        if(!StringUtils.isEmpty(phoneNumber)) {
            AliyunSMS.SendMessage(phoneNumber,verificationCode);
            System.out.println("验证码已发送:==>" + verificationCode);
        }

        //打包
        map.put("phoneNumber",phoneNumber);
        map.put("code",verificationCode);

        try{
            //前端一定要携带sessionid回传
            String sid="";
            if(!Objects.isNull(yuLiStudioLoginUser.getSessionId())){
                sid=yuLiStudioLoginUser.getSessionId();
            }
            if(!StringUtils.isEmpty(sid)){
                System.out.println("同一个用户操作");
                System.out.println(sid);
            }else{
                //生成1个全局唯一的sessionid用于发送到客户端进行后续会话同步操作，读取redis存储信息
                sid=request.getSession().getId();
                System.out.println("当前会话id:==>"+sid);
            }

            //封装对象进Redis
            redisTemplate.opsForValue().set("sid",map);
            return R.ok("短信验证码发送成功").put("sid",sid); //为了保持同一session会话
        }
        catch (Exception e) {
            return R.error(408,"短信发送失败");
        }
    }



    //检查短信验证码过期时间
    private Boolean CheckSMSexpiredTime(HttpSession session){
        if(Objects.isNull(session.getAttribute("expiredTime"))) return false;
        Long expiredTime=(Long) session.getAttribute("expiredTime");
        Long nowTime = System.currentTimeMillis();
        System.out.println("时间戳对比"+((nowTime-expiredTime)/60000)+"分钟");
        return ((nowTime-expiredTime)/60000)>1?true:false;
    }


    /**
     * 获取课程列表信息(支持分页数据)
     *
     * 前端传入以下参数,经过startPage()初始化
     * ----------------------------------
     * pageNum: 1,
     * pageSize: 10,
     */
    @Anonymous
    @GetMapping("/getCourses")
    public TableDataInfo getCourses(Courses courses) {
        startPage();
        List<Courses> list = coursesService.selectCoursesList(courses);
        return getDataTable(list);
    }




    /**
     * 获取单挑课程信息和所有相关视频
     */
    @GetMapping("/getCoursesById/{id}")
    public R getCoursesById(@PathVariable Long id) {
        try
        {
            Courses courses=coursesService.selectCoursesById(id);
            HashMap<String,Object> map=new HashMap<>();
            map.put("courses",courses);
            map.put("videosList", videosService.selectCourseVideosList(id));
            return R.ok().put("data",map);
        }
        catch (Exception e)
        {
            return R.error(408,"获取课程信息失败");
        }
    }




    /**
     * 添加预约
     */
    @Anonymous
    @PostMapping("/addapply")
    public R addapply(@RequestBody Subscribes subscribes) throws Exception {
        try
        {
            //查询是否有重复预约
            Subscribes newSubscribes=subscribesService.selectSubscribes(subscribes);
            if(newSubscribes==null){
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formattedDate = dateFormat.format(new Date());
                subscribes.setCoursetime(formattedDate);

                subscribesService.insertSubscribes(subscribes);
                //发送预约短信通知
                //AliyunSMS.SendMessage(subscribes);
                //19928352090
                AliyunSMS.SendSubscribesMessage("19928352090",subscribes.getCoursename(),formattedDate);

                return R.ok("预约成功");
            }else{
                return R.ok("已预约,请勿重复提交");
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加预约失败");
        }
    }



    /**
     * 获取预约
     */
    @Anonymous
    @PostMapping("/getSubScribes")
    public R getSubScribes(@RequestBody Subscribes subscribes) throws Exception {

        System.out.println("预约课程:");
        System.out.println(subscribes);
        System.out.println(subscribes.getToken());

        String token=subscribes.getToken();
        String sessionid=jwtUtils.getToken(token).getClaim("sessionid").toString().replace("\"","");
        System.out.println("sessionid==>"+sessionid);

        //获取用户信息
        Students studentsinfo=(Students)redisTemplate.opsForValue().get("student_"+sessionid);
        System.out.println("用户信息");
        System.out.println(studentsinfo);
        Long userId=studentsinfo.getId();

        try
        {
            List<Subscribes> subscribesList=subscribesService.selectSubscribesByUserId(userId);
            if(subscribesList.size()>0){
                return R.ok().put("subscribesList",subscribesList);
            }else{
                return R.error("没有预约申请");
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加预约失败");
        }
    }




    /**
     * 获取机构信息
     */
    @GetMapping("/getOrgs")
    public R getOrgs() throws Exception {
        try
        {
            Orgs orgs=orgsService.selectOrgsById(1L);
            if(orgs!=null){
                return R.ok().put("data",orgs);
            }else{
                return null;
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加预约失败");
        }
    }




    /**
     * 获取文章
     */
    @Anonymous
    @PostMapping("/getArticles")
    public R getArticles(@RequestBody Articles articles) throws Exception {
        try
        {
            Articles arts=articlesService.selectArticleByType(articles.getAtype());
            if(arts!=null){
                return R.ok("获取文章成功").put("data",arts);
            }else{
                return null;
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"获取文章失败");
        }
    }



    /**
     * 添加我的课单
     */
    @Anonymous
    @PostMapping("/addFavs")
    public R addFavs(@RequestBody Myfavs myfavs) throws Exception {
        try
        {
            //查询收藏是否已存在
            Long userid=Long.valueOf(myfavs.getUserid());
            Long courseid=Long.valueOf(myfavs.getCourseid());
            Myfavs newMyfavs=myfavsService.selectMyfavsByUserIdAndCourseId(userid,courseid);
            if(newMyfavs==null){
                myfavsService.insertMyfavs(myfavs);
                return R.ok("添加成功").put("dataid",myfavs.getId());
            }else{
                return R.ok("已收藏").put("dataid",newMyfavs.getId());
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加收藏课单失败");
        }
    }
    /**
     * 移除我的课单
     */
    @Anonymous
    @PostMapping("/removeFavs")
    public R removeFavs(@RequestBody Myfavs myfavs) throws Exception {
        try
        {
            //查询收藏是否已存在
            Long dataid=Long.valueOf(myfavs.getId());
            myfavsService.deleteMyfavsById(dataid);
            return R.ok("移除成功");
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"移除课单失败");
        }
    }

    /**
     * 检查是否已收藏
     */
    @Anonymous
    @PostMapping("/checkFavs")
    public R checkFavs(@RequestBody Myfavs myfavs) throws Exception {
        try
        {
            //查询收藏是否已存在
            Long userid=Long.valueOf(myfavs.getUserid());
            Long courseid=Long.valueOf(myfavs.getCourseid());
            Myfavs newMyfavs=myfavsService.selectMyfavsByUserIdAndCourseId(userid,courseid);
            if(newMyfavs!=null){
                return R.ok().put("dataid",newMyfavs.getId());
            }else{
                return R.error(400,"还未收藏");
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加收藏课单失败");
        }
    }


    /**
     * 获取我的课单
     */
    @Anonymous
    @PostMapping("/getMyFavsList")
    public R getMyFavsList(@RequestBody Myfavs myfavs) throws Exception {
        try
        {
            //查询收藏是否已存在
            myfavs.setUserid(Integer.valueOf(myfavs.getUserid()));
            List<Myfavs> newMyfavs=myfavsService.selectMyfavsList(myfavs);
            List<Courses> CourseList=new ArrayList<>(); //课程详细列表

            newMyfavs.forEach(item->{
                System.out.println(item);
                Courses cur=coursesService.selectCoursesById(Long.valueOf(item.getCourseid()));
                CourseList.add(cur);
            });

            return R.ok("获取我的课单成功").put("data",CourseList);
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"添加收藏课单失败");
        }
    }




    /**
     * 获取活动海报
     */
    @Anonymous
    @PostMapping("/getActivitys")
    public R getActivitys(@RequestBody Activitys activitys) throws Exception {
        try
        {
            List<Activitys> actsList=activitysService.selectActivitysList(activitys);
            if(actsList!=null){
                return R.ok("获取活动海报成功").put("data",actsList);
            }else{
                return null;
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"获取活动海报失败");
        }
    }







    /**
     * 查找学员课堂信息(支持分页数据)
     *
     * 前端传入以下参数,经过startPage()初始化进行分页,通过getMappding请求
     * --------------------------------------------------------------
     * pageNum: 1,
     * pageSize: 10,
     */
    @Anonymous
    @GetMapping("/getStudentClocking")
    public TableDataInfo getStudentClocking(Clocking clocking) {
//        System.out.println("clocking===>");
//        System.out.println(clocking);
        startPage();
        List<Clocking> list = iClockingService.selectClockingList(clocking);
        return getDataTable(list);
    }


    /**
     *  获取学习风采(支持分页数据)
     *
     * 前端传入以下参数,经过startPage()初始化进行分页,通过getMappding请求
     * --------------------------------------------------------------
     * pageNum: 1,
     * pageSize: 10,
     */
    @Anonymous
    @GetMapping("/getFengCai")
    public TableDataInfo getFengCai(Photos photos) {
        startPage();
        List<Photos> list = photosService.selectPhotosList(photos);
        return getDataTable(list);
    }



    /**
     * 更新学生信息
     */
    @Anonymous
    @PostMapping("/updateStudents")
    public R updateStudents(@RequestBody Students students) throws Exception {
        try
        {
            studentsService.updateStudents(students);
            return R.ok("更新学生信息成功").put("data",students);
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"更新学生信息失败"+e.getMessage());
        }
    }


    /**
     * 获取轮播图广告图
     */
    @Anonymous
    @PostMapping("/GetAdimgsData")
    public R GetAdimgsData(@RequestBody Adimgs adimgs) throws Exception {
        try
        {
            List<Adimgs> imgDatas=adimgsService.selectAdimgsList(adimgs);
            return R.ok("更新学生信息成功").put("data",imgDatas);
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"更新学生信息失败"+e.getMessage());
        }
    }




    /**
     * 是否打开课程开关
     */
    @Anonymous
    @PostMapping("/getOpenCourse")
    public R getOpenCourse(@RequestBody Openclose openclose) throws Exception {
        try
        {
            return R.ok().put("data",opencloseService.selectOpencloseList(openclose));
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"是否打开课程开关"+e.getMessage());
        }
    }




    /**
     * 更新登录密码
     */
    @Anonymous
    @PostMapping("/updatePassword")
    public R updatePassword(@RequestBody Students students) throws Exception {
        try
        {
            studentsService.updateStudents(students);
            //查询是否有重复预约
            return R.ok("登录密码修改成功");
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return R.error(408,"登录密码修改失败");
        }
    }

} //Class End
